pforce
and pdelay
plet
and phoist
are the two main tools to use when focusing on optimizations;
this is because they significantly reduce both script size and cost of execution.
pforce
and pdelay
do slightly increase the size of a script but when used properly they can save you quite a bit on execution costs.
As we know, plu-ts
is strictly evaluated, meaning that arguments are evaluated before being passed to a function.
We can opt out of this behavior using pdelay
which wraps a term of any type in a delayed
type so a term of type int
becomes delayed( int )
if passed to pdelay
. A delayed
type can be unwrapped only using pforce
, that finally executes the term.
There are two main reasons for why we would want to do this:
- delaying the execution of some term we might not need at all
- prevent to raise unwanted errors
One example of the use of pforce
and pdelay
is the pif
function.
In fact, the base if then else function is pstrictIf
, however when we use an if then else statement we only need one of the two arguments to be actually evaluated.
So when we call pif
, it is just as if we were doing something like:
pforce(
pstrictIf( delayed( returnType ) )
.$( myCondtion )
.$(
pdelay( caseTrue )
)
.$(
pdelay( caseFalse )
)
)
So that we only evaluate what we need.
Not only that, but if one of the two branches throws an error but we don't need it, everything goes through smoothly:
pforce(
pstrictIf( delayed( int ) )
.$( true )
.$(
pdelay( pInt( 42 ) )
)
.$(
pdelay( perror( int ) )
)
)
Here, everything is ok.
If instead we just used the plain pstrictIf
pstrictIf( int )
.$( pBool( true ) )
.$( pInt( 42 ) )
.$( perror( int ) ) // KABOOM !!!
This results in an error, because the error is evaluated before being passed as argument.